package com.rising.face.ali.bishi.threadprint5;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: rising
 * @Description:
 * // 设计一个多线程打印程序，第i个线程只打印i-1数字，比如第1个线程打印数字0，第2个线程只打印数字1，依次类推。
 * // 任意给定一个数字序列，比如5743958490143058，能够使用该程序打印出来。
 * @Date: create in 2021/3/26 21:44
 */

public class ThreadPrint {
    private int currentThread = 0;
    private int index = 0;
    private int[] xulie = null;

    private Lock lock = new ReentrantLock();

    private Condition[] conditions = null;

    //传入第一个唤醒线程
    public ThreadPrint(String currentThreads) {
        char[] chars = currentThreads.toCharArray();
        xulie = new int[chars.length];
        for (int i = 0; i < chars.length; i++) {
            xulie[i] = Integer.valueOf(String.valueOf(chars[i]));
        }

        //第一个打印的线程
        currentThread = xulie[0];

        conditions = new Condition[10];
        for (int i = 0; i < 10; i ++) {
            conditions[i] = lock.newCondition();
        }
    }

    public void print0() {
        int flag = 0;
        try {
            lock.lock();
            while (true) {
                //等待唤醒
                while (currentThread != flag) {
                    conditions[flag].await();
                }
                System.out.println(Thread.currentThread().getName() + " -- " + flag);
                //找到下一个需要唤醒的线程
                index++;
                currentThread = xulie[index];
                //唤醒线程
                conditions[currentThread].signal();
            }
        } catch (Exception e) {

        } finally {
            lock.unlock();
        }
    }

    public void print1() {
        int flag = 1;
        try {
            lock.lock();
            while (true) {
                //等待唤醒
                while (currentThread != flag) {
                    conditions[flag].await();
                }
                System.out.println(Thread.currentThread().getName() + " -- " + flag);
                //找到下一个需要唤醒的线程
                index++;
                currentThread = xulie[index];
                //唤醒线程
                conditions[currentThread].signal();
            }
        } catch (Exception e) {

        } finally {
            lock.unlock();
        }
    }

    public void print2() {
        int flag = 2;
        try {
            lock.lock();
            while (true) {
                //等待唤醒
                while (currentThread != flag) {
                    conditions[flag].await();
                }
                System.out.println(Thread.currentThread().getName() + " -- " + flag);
                //找到下一个需要唤醒的线程
                index++;
                currentThread = xulie[index];
                //唤醒线程
                conditions[currentThread].signal();
            }
        } catch (Exception e) {

        } finally {
            lock.unlock();
        }
    }

    public void print3() {
        int flag = 3;
        try {
            lock.lock();
            while (true) {
                //等待唤醒
                while (currentThread != flag) {
                    conditions[flag].await();
                }
                System.out.println(Thread.currentThread().getName() + " -- " + flag);
                //找到下一个需要唤醒的线程
                index++;
                currentThread = xulie[index];
                //唤醒线程
                conditions[currentThread].signal();
            }
        } catch (Exception e) {

        } finally {
            lock.unlock();
        }
    }

    public void print4() {
        int flag = 4;
        try {
            lock.lock();
            while (true) {
                //等待唤醒
                while (currentThread != flag) {
                    conditions[flag].await();
                }
                System.out.println(Thread.currentThread().getName() + " -- " + flag);
                //找到下一个需要唤醒的线程
                index++;
                currentThread = xulie[index];
                //唤醒线程
                conditions[currentThread].signal();
            }
        } catch (Exception e) {

        } finally {
            lock.unlock();
        }
    }

    public void print5() {
        int flag = 5;
        try {
            lock.lock();
            while (true) {
                //等待唤醒
                while (currentThread != flag) {
                    conditions[flag].await();
                }
                System.out.println(Thread.currentThread().getName() + " -- " + flag);
                //找到下一个需要唤醒的线程
                index++;
                currentThread = xulie[index];
                //唤醒线程
                conditions[currentThread].signal();
            }
        } catch (Exception e) {

        } finally {
            lock.unlock();
        }
    }

    public void print6() {
        int flag = 6;
        try {
            lock.lock();
            while (true) {
                //等待唤醒
                while (currentThread != flag) {
                    conditions[flag].await();
                }
                System.out.println(Thread.currentThread().getName() + " -- " + flag);
                //找到下一个需要唤醒的线程
                index++;
                currentThread = xulie[index];
                //唤醒线程
                conditions[currentThread].signal();
            }
        } catch (Exception e) {

        } finally {
            lock.unlock();
        }
    }

    public void print7() {
        int flag = 7;
        try {
            lock.lock();
            while (true) {
                //等待唤醒
                while (currentThread != flag) {
                    conditions[flag].await();
                }
                System.out.println(Thread.currentThread().getName() + " -- " + flag);
                //找到下一个需要唤醒的线程
                index++;
                currentThread = xulie[index];
                //唤醒线程
                conditions[currentThread].signal();
            }
        } catch (Exception e) {

        } finally {
            lock.unlock();
        }
    }

    public void print8() {
        int flag = 8;
        try {
            lock.lock();
            while (true) {
                //等待唤醒
                while (currentThread != flag) {
                    conditions[flag].await();
                }
                System.out.println(Thread.currentThread().getName() + " -- " + flag);
                //找到下一个需要唤醒的线程
                index++;
                currentThread = xulie[index];
                //唤醒线程
                conditions[currentThread].signal();
            }
        } catch (Exception e) {

        } finally {
            lock.unlock();
        }
    }

    public void print9() {
        int flag = 9;
        try {
            lock.lock();
            while (true) {
                //等待唤醒
                while (currentThread != flag) {
                    conditions[flag].await();
                }
                System.out.println(Thread.currentThread().getName() + " -- " + flag);
                //找到下一个需要唤醒的线程
                index++;
                currentThread = xulie[index];
                //唤醒线程
                conditions[currentThread].signal();
            }
        } catch (Exception e) {

        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        //String currentThreads = "5743958490143058";
        String currentThreads = "57";
        ThreadPrint threadPrint = new ThreadPrint(currentThreads);

        new Thread(new Runnable() {
            @Override
            public void run() {
                threadPrint.print0();
            }
        }, "Thread1").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                threadPrint.print1();
            }
        }, "Thread2").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                threadPrint.print2();
            }
        }, "Thread3").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                threadPrint.print3();
            }
        }, "Thread4").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                threadPrint.print4();
            }
        }, "Thread5").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                threadPrint.print5();
            }
        }, "Thread6").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                threadPrint.print6();
            }
        }, "Thread7").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                threadPrint.print7();
            }
        }, "Thread8").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                threadPrint.print8();
            }
        }, "Thread9").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                threadPrint.print9();
            }
        }, "Thread0").start();
    }
}
